package cn.ly.jdk8new.lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.junit.Test;

public class LambdaTest {
	
	@Test
	public void testRunnableLambda(){
		new Thread(new Runnable(){
			@Override
			public void run() {
				System.out.println("Runnable：匿名内部类");
			}
		}).start();
		new Thread( ()->{System.out.println("Runnablel：lambda表达式");}).start();;
	}
	
	@Test
	public void testForEach(){
		String sep = ",";
		List<String> list = new ArrayList<String>();
		list.add("1a");
		list.add("2b");
		list.add("3c");
		list.forEach(new Consumer(){
			@Override
			public void accept(Object t) {
				System.out.print(t + sep);
			}
		});
		System.out.println();
		list.sort(new Comparator(){
			@Override
			public int compare(Object o1, Object o2) {
				return ((String)o1).compareTo((String)o2);
			}
			
		});
		list.sort( (e1,e2)->e1.compareTo(e2) );              //这种方法可以重写比较方法，重新自定义排序规则
		list.sort(String::compareTo);                        //这种方式只是简单的方法调用，但是不能重写此方法
		
		list.forEach( (String t) -> System.out.print(t + sep));     
		System.out.println(); 
		list.forEach(System.out::print);                     //参数都可以省了
		
		List<Integer> ints = Arrays.asList(1, 2, 3);
		ints.sort(Integer::compare);
		System.out.println();
		list.forEach(System.out::print);                     //方法引用：就是lambda表达式的简写方式：Class::method 或者 Class.obj对象::method
		
		//set以及其它集合有forEach和sort都可以使用lambda表达式
		Set<String> set = new HashSet<String>();
		set.add("zhang3");
		set.add("li4");
		set.add("wang5");
		System.out.println();
		set.forEach( (String t) -> System.out.print(t + sep));
	}
	
	@Test
	public void testFunInterface(){
		FunInterface f = new MyFunIterObj();
		f.testFunInterface();
		f.myDefault2();
		MyFunIterObj.myStaticMethod();//函数式接口的静态方法不能继承
		FunInterface.myStaticMethod();
		FunInterface.myStaticMethod2();
		new FunInterface(){
			@Override
			public void testFunInterface() {
				System.out.println("this is a FunInterface匿名内部类");
			}
		};
		MyFunObj myFunObj = new MyFunObj();
		myFunObj.testFun1(()->{
			System.out.println("this is a lambda表达式");
		});
		
		myFunObj.testFun2(()->{
			System.out.println("this is a common interface lambda表达式");
		});
		myFunObj.testFun2(MyFunIterObj::new);//自定义的类，实现了CommonInterface接口的类可以使用方法引用方式。
	}
	
	@Test
	public void testCollection(){
		List<String> list = Arrays.asList("a1","b2","c3");
		Stream<String> stream = list.stream();//需要用到泛型
		//Stream stream1 = stream.map(word-> word.length()));
		Stream stream1 = stream.map(word-> (new StringBuilder(word).append(" test stream")).toString());
		//System.out.println(stream1.count());
		stream1.forEach(System.out::println);  //stream是一个序列，只能使用一次
		Stream stream2 = list.stream().filter(word -> word.indexOf("a") >= 0);
		stream2.forEach(System.out::println);
		
		Supplier< Car > supplier = Car::new;
		final Car car = Car.create( supplier );
		final List< Car > cars = Arrays.asList( car );
		System.out.println("cars : " + cars);
		
	}
	
	static class Car {
	    public static Car create( final Supplier< Car > supplier ) {
	        return supplier.get();
	    }              

	    public static void collide( final Car car ) {
	        System.out.println( "Collided " + car.toString() );
	    }

	    public void follow( final Car another ) {
	        System.out.println( "Following the " + another.toString() );
	    }

	    public void repair() {   
	        System.out.println( "Repaired " + this.toString() );
	    }
	}
	
	public static void main(String[] args) {
		
	}

}


